<template>
    <div>
        <el-card style="display: inline-flex;width:100%;">
           <el-row :gutter="20">
            <el-col :span="10"><div>
                <el-select v-model="valueInput" clearable placeholder="请选择事件类型">
            <el-option
            v-for="item in options"
            :key="item.value"
            :label="item.label"
            :value="item.value">
            </el-option>
            </el-select>
            </div>
            </el-col>
            <el-col :span="10">
                <div>
                    <el-autocomplete
                    class="inline-input"
                    v-model="valueInput"
                    :fetch-suggestions="querySearch"
                    placeholder="请输入事件类型"
                    :trigger-on-focus="false"
                    @select="handleSelect"
                    ></el-autocomplete>
                </div>
            </el-col>
            <el-col :span="4">
                <el-button type="primary" @click="select" style="margin-left: 10px;">查询</el-button>
            </el-col>
           </el-row>     
        </el-card>
        <el-card>
            <div ref="active_dates_and_times" id="active_dates_and_times" style="height:400px;width:100%"></div>
        </el-card>
        <el-card>
          <div ref="stars" id="stars" style="height: 400px;width: 100%;"></div>
        </el-card>
        <el-card>
          <div ref="technical_fork" id="technical_fork" style="height: 400px;width: 100%;"></div>
        </el-card>
        <el-card >
            <div ref="participants" id="participants" style="height: 800px;width: 100%;"></div>
        </el-card>
        <el-card >
            <div ref="new_contributors" id="new_contributors" style="height: 1000px;width: 100%;"></div>
        </el-card>
        <el-card>
          <div ref="inactive_contributors" id="inactive_contributors" style="height: 400px;width: 100%;"></div>
        </el-card>
        <el-card>
          <div ref="bus_factor" id="bus_factor" style="height: 400px;width: 100%;"></div>
        </el-card>
        <el-card>
          <div ref="issues_closed_and_new" id="issues_closed_and_new" style="height: 400px;width: 100%;"></div>
        </el-card>
        <el-card>
          <div ref="issues_comments" id="issues_comments" style="height: 400px;width: 100%;"></div>
        </el-card>
        <el-card>
          <div ref="issue_response_time" id="issue_response_time" style="height: 400px;width: 100%;"></div>
        </el-card>
        <el-card>
          <div ref="issue_resolution_duration" id="issue_resolution_duration" style="height: 400px;width: 100%;"></div>
        </el-card>
        <el-card>
          <div ref="issue_age" id="issue_age" style="height: 400px;width: 100%;"></div>
        </el-card>
        <el-card>
          <div ref="code_change_lines" id="code_change_lines" style="height: 400px;width: 100%;"></div>
        </el-card>
        <el-card>
          <div ref="change_requests" id="change_requests" style="height: 400px;width: 100%;"></div>
        </el-card>
        <el-card>
          <div ref="change_request_response_time" id="change_request_response_time" style="height: 400px;width: 100%;"></div>
        </el-card>
        <el-card>
          <div ref="change_request_resolution_duration" id="change_request_resolution_duration" style="height: 400px;width: 100%;"></div>
        </el-card>
        <el-card>
          <div ref="change_request_age" id="change_request_age" style="height: 400px;width: 100%;"></div>
        </el-card>
        <el-card>
          <div ref="activity_details" id="activity_details" style="height: 600px;width: 100%;"></div>
          <div style="display: flex;">
            <el-button @click="replay" type="primary">重放
          </el-button>
          <el-button @click="pause" type="danger">暂停</el-button>
          <el-button @click="resume" type="success">继续</el-button>
          
          </div>
        </el-card>
    </div>
</template>

<script>
import * as echarts from 'echarts';
import axios from 'axios';
let crsResponseAgeK={
      title: {
        text: 'Change request age',
        left: 'center'
      },
      tooltip: {
    trigger: 'axis'
     },
      legend: {
        top:'bottom',
        data:['quantiles box plot','average']
      },
      xAxis: {
        data: [],
      },
      yAxis: {
        type: 'value',
        name: 'days',
      },
      series: [
        {
          type: 'candlestick',
          name: 'quantiles box plot',
          data: [],
          itemStyle: {
            color: 'rgba(0, 0, 180, 0.4)',
            color0: 'rgba(0, 0, 180, 0.4)',
            borderColor: 'rgba(0, 0, 180, 0.4)',
            borderColor0: 'rgba(0, 0, 180, 0.4)',
          }
        }, {
          type: 'line',
          name: 'average',
          data: [],
          smooth: true,
          showSymbol: false,
        }
      ]
    };
let crsResolutionDurationK={
      title: {
        text: 'Change request resolution duration',
        left: 'center'
      },
      tooltip: {
    trigger: 'axis'
     },
      legend: {
        top:'bottom',
        data:['quantiles box plot','average']
      },
      xAxis: {
        data: [],
      },
      yAxis: {
        type: 'value',
        name: 'days',
      },
      series: [
        {
          type: 'candlestick',
          name: 'quantiles box plot',
          data: [],
          itemStyle: {
            color: 'rgba(0, 0, 180, 0.4)',
            color0: 'rgba(0, 0, 180, 0.4)',
            borderColor: 'rgba(0, 0, 180, 0.4)',
            borderColor0: 'rgba(0, 0, 180, 0.4)',
          }
        }, {
          type: 'line',
          name: 'average',
          data: [],
          smooth: true,
          showSymbol: false,
        }
      ]
    };
let crsResponseTimeK={
      title: {
        text: 'Change request response time',
        left: 'center'
      },
      tooltip: {
    trigger: 'axis'
     },
      legend: {
        top:'bottom',
        data:['quantiles box plot','average']
      },
      xAxis: {
        data: [],
      },
      yAxis: {
        type: 'value',
        name: 'days',
      },
      series: [
        {
          type: 'candlestick',
          name: 'quantiles box plot',
          data: [],
          itemStyle: {
            color: 'rgba(0, 0, 180, 0.4)',
            color0: 'rgba(0, 0, 180, 0.4)',
            borderColor: 'rgba(0, 0, 180, 0.4)',
            borderColor0: 'rgba(0, 0, 180, 0.4)',
          }
        }, {
          type: 'line',
          name: 'average',
          data: [],
          smooth: true,
          showSymbol: false,
        }
      ]
    };
let changeRequestBar={
  tooltip: {
    trigger: 'axis',
  },
        title: {
          text: 'Changes requests',
          left: 'center'
        },
        legend: {
          data: ['New', 'Accpeted', 'Reviews'],
          top:'bottom'
        },
        xAxis: {
          type: 'category',
          data: [],
        },
        yAxis: [{ type: 'value' },
        { type: 'value' }
        ],
        series: [
          {
            type: 'bar',
            stack: 'Total',
            silent: true,
            itemStyle: {
              borderColor: 'transparent',
              color: 'transparent'
            },
            emphasis: {
              itemStyle: {
                borderColor: 'transparent',
                color: 'transparent'
              }
            },
            // data: [],
          },
          {
            type: 'bar',
            stack: 'CloseTotal',
            silent: true,
            itemStyle: {
              borderColor: 'transparent',
              color: 'transparent'
            },
            emphasis: {
              itemStyle: {
                borderColor: 'transparent',
                color: 'transparent'
              }
            },
            // data: [],
          },
          {
            name: 'New',
            type: 'bar',
            stack: 'Total',
            itemStyle: {
              color: 'green',
            },
            data: [],
          },
          {
            name: 'Accpeted',
            type: 'bar',
            itemStyle: {
              color: 'red',
            },
            stack: 'CloseTotal',
            data: [],
          },
          {
            name: 'Reviews',
            type: 'line',
            data: [],
            yAxisIndex: 1,
            smooth:true
          }
        ]
      };
let codeChangeLinesL={
  tooltip: {
    trigger: 'axis',
  },
  title: {
    left: 'center',
    text: 'Code change lines'
  },
  legend: {
        top:'bottom',
        data:['addCode','removeCode','allChange']
      },
  xAxis: {
    data:[]
  },
  yAxis: {
    type: 'value',
    boundaryGap: [0, '100%']
  },
  series: [
    {
      name: 'addCode',
      type: 'line',
      smooth: true,
      symbol: 'none',
      areaStyle: {},
      data: []
    },
    {
      name: 'removeCode',
      type: 'line',
      smooth: true,
      symbol: 'none',
      areaStyle: {},
      data: []
    },
    {
      name: 'allChange',
      type: 'line',
      smooth: true,
      symbol: 'none',
      areaStyle: {},
      data: []
    }
  ]
};
let issueAgeK={
      title: {
        text: 'Issue age',
        left: 'center'
      },
      tooltip: {
    trigger: 'axis'
     },
      legend: {
        top:'bottom',
        data:['quantiles box plot','average']
      },
      xAxis: {
        data: [],
      },
      yAxis: {
        type: 'value',
        name: 'days',
      },
      series: [
        {
          type: 'candlestick',
          name: 'quantiles box plot',
          data: [],
          itemStyle: {
            color: 'rgba(0, 0, 180, 0.4)',
            color0: 'rgba(0, 0, 180, 0.4)',
            borderColor: 'rgba(0, 0, 180, 0.4)',
            borderColor0: 'rgba(0, 0, 180, 0.4)',
          }
        }, {
          type: 'line',
          name: 'average',
          data: [],
          smooth: true,
          showSymbol: false,
        }
      ]
    };
let issueResolutionK={
      title: {
        text: 'Issue resolution duration',
        left: 'center'
      },
      tooltip: {
    trigger: 'axis'
     },
      legend: {
        top:'bottom',
        data:['quantiles box plot','average']
      },
      xAxis: {
        data: [],
      },
      yAxis: {
        type: 'value',
        name: 'days',
      },
      series: [
        {
          type: 'candlestick',
          name: 'quantiles box plot',
          data: [],
          itemStyle: {
            color: 'rgba(0, 0, 180, 0.4)',
            color0: 'rgba(0, 0, 180, 0.4)',
            borderColor: 'rgba(0, 0, 180, 0.4)',
            borderColor0: 'rgba(0, 0, 180, 0.4)',
          }
        }, {
          type: 'line',
          name: 'average',
          data: [],
          smooth: true,
          showSymbol: false,
        }
      ]
    };
let issueResponseTimeK={
      title: {
        text: 'Issue response time',
        left: 'center'
      },
      tooltip: {
    trigger: 'axis'
     },
      legend: {
        top:'bottom',
        data:['quantiles box plot','average']
      },
      xAxis: {
        data: [],
      },
      yAxis: {
        type: 'value',
        name: 'days',
      },
      series: [
        {
          type: 'candlestick',
          name: 'quantiles box plot',
          data: [],
          itemStyle: {
            color: 'rgba(0, 0, 180, 0.4)',
            color0: 'rgba(0, 0, 180, 0.4)',
            borderColor: 'rgba(0, 0, 180, 0.4)',
            borderColor0: 'rgba(0, 0, 180, 0.4)',
          }
        }, {
          type: 'line',
          name: 'average',
          data: [],
          smooth: true,
          showSymbol: false,
        }
      ]
    };
let commentsBar={
    title:{
    text:'Issue comments',
    left:'center'
  },
  tooltip: {
    trigger: 'axis'
  },

  xAxis: {
    type: 'category',
    data: []
  },
  yAxis: {
    type: 'value'
  },
  legend:{
    data:['comments','allcomments'],
    top:'bottom'
  },
  series: [
    {
      name:'comments',
      data: [],
      type: 'bar'
    },
    {
        name:'allcomments',
        data:[],
        type:'line',
        smooth:true
    }
  ]
};
let issuesNewAndClosedK = {
        title: {
          text: 'Issues new and closed',
          left: 'center'
        },
        tooltip: {
    trigger: 'axis'
   },
        legend: {
          data: ['New', 'Closed','issuesNewBase','issuesClosedBase'],
          top:'bottom'
        },
        xAxis: {
          type: 'category',
          data: [],
        },
        yAxis: [{ type: 'value', min: 0 }, { type: 'value' }],
        series: [
          {
            name:'issuesNewBase',
            type: 'bar',
            stack: 'Total',
            silent: true,
            itemStyle: {
              borderColor: 'transparent',
              color: 'transparent'
            },
            emphasis: {
              itemStyle: {
                borderColor: 'transparent',
                color: 'transparent'
              }
            },
            data: [],
          },
          {
            name:'issuesClosedBase',
            type: 'bar',
            stack: 'CloseTotal',
            silent: true,
            itemStyle: {
              borderColor: 'transparent',
              color: 'transparent'
            },
            emphasis: {
              itemStyle: {
                borderColor: 'transparent',
                color: 'transparent'
              }
            },
            data: [],
          },
          {
            name: 'New',
            type: 'bar',
            stack: 'Total',
            itemStyle: {
              color: 'green',
            },
            data: []
          },
          {
            name: 'Closed',
            type: 'bar',
            itemStyle: {
              color: 'red',
            },
            stack: 'CloseTotal',
            data: [],
          }
        ]
      };
let busFactorBar={
  title:{
    text:'Bus Factor',
    left:'center'
  },
  tooltip: {
    trigger: 'axis'
   },
  xAxis: {
    type: 'category',
    data: []
  },
  yAxis: {
    type: 'value'
  },
  legend:{
    data:['busFactorBar','busFactorLine'],
    top:'bottom'
  },
  series: [
    {
      name:'busFactorBar',
      data: [],
      type: 'bar'
    },{
      name:'busFactorLine',
      data:[],
      type:'line',
      smooth:true
    }
  ]
};
let inactiveContributorChart = {
  title:{
    text:'Inactive contributors',
    left:'center'
  },
  tooltip: {
    trigger: 'axis'
   },
  xAxis: {
    type: 'category',
    data: []
  },
  yAxis: {
    type: 'value'
  },
  series: [
    {
      data: [],
      type: 'bar'
    }
  ]
};
//Participants图表数据开始
let participantPie={
    title:{
    text:'Participants',
    left:'center'
  },
  tooltip: {
    trigger: 'item'
  },
    legend: {
    top: 'bottom'
  },
  toolbox: {
    show: true,
    feature: {
      mark: { show: true },
      dataView: { show: true, readOnly: false },
      restore: { show: false },
      saveAsImage: { show: true }
    }
  },
  series: [
    {
      name: '参与者',
      type: 'pie',
      radius: [50, 250],
      center: ['50%', '50%'],
      roseType: 'area',
      itemStyle: {
        borderRadius: 8
      },
      data: [],
    }
  ]
};
//Participants图表数据结束
//Technical fork图表数据开始
let technicalBar={
    title:{
    text:'Technical fork',
    left:'center'
  },

  tooltip: {
    trigger: 'axis'
  },
  xAxis: {
    type: 'category',
    data: []
  },
  yAxis: {
    type: 'value'
  },
  legend:{
    data:['forks','allForks'],
    top:'bottom'
  },
  series: [
    {
      name:'forks',
      data: [],
      type: 'bar'
    },
    {
        name:'allForks',
        data:[],
        type:'line',
        smooth:true
    }
  ]
};
//Technical fork图表数据结束
//Stars图表数据开始
let starBar={
    title:{
    text:'Stars',
    left:'center'
  },
  tooltip: {
    trigger: 'axis'
  },

  xAxis: {
    type: 'category',
    data: []
  },
  yAxis: {
    type: 'value'
  },
  legend:{
    data:['stars','allStars'],
    top:'bottom'
  },
  series: [
    {
      name:'stars',
      data: [],
      type: 'bar'
    },
    {
        name:'allStars',
        data:[],
        type:'line',
        smooth:true
    }
  ]
};
//Stars图表数据结束
//Active dates and times图表数据开始
let activeHeatMap={
    title:{
    text:'Active dates and times',
    left:'center'
  },
    tooltip: {
    position: 'top'
  },
  grid: {
    height: '50%',
    top: '10%'
  },
  xAxis: {
    type: 'category',
    data: [],
    splitArea: {
      show: true
    }
  },
  yAxis: {
    type: 'category',
    data: [],
    splitArea: {
      show: true
    }
  },
  visualMap: {
    min: 0,
    max: 10,
    calculable: true,
    orient: 'horizontal',
    left: 'center',
    bottom: '15%'
  },
  series: [
    {
      name: 'hours num',
      type: 'heatmap',
      data: [],
      label: {
        show: true
      },
      emphasis: {
        itemStyle: {
          shadowBlur: 10,
          shadowColor: 'rgba(0, 0, 0, 0.5)'
        }
      }
    }
  ]
};
//Active dates and times图表数据结束
// 定义一个根路径
const ROOT_PATH='https://oss.x-lab.info/open_digger/github/X-lab2017/open-digger/';
    export default {
        name:'MetricView',
        data(){
            return{
                timeouts:[],//存储定时器，在必要时需要清除计时器，比如在暂停之后点重新播放，如果不清楚计时器，就会一下市暂停之前的月份，一下是重新开始的月份
                isPaused:false,
                currentIndex:0,
                colorMap: new Map(),
                updateFrequency: 2000,
                playing:false,//控制activity details图表的播放
                activityDetailsChart:null,//activity details图表实例
                months:[],//activity details的月份
                activityData:null,//activity details的数据源
                contributorData:null,//contributorData用于配合transformData函数给new_contributors图表数据源
                contributorTree:null,//contributorTree图表实例
                activeValue:[],
                valueInput:'',
                data:[],//搜索框的值
                options: [{
                value: 'Active dates and times',
                label: 'Active dates and times'
                }, {
                value: 'Stars',
                label: 'Stars'
                }, {
                value: 'Technical fork',
                label: 'Technical fork'
                },
                {
                value: 'Participants',
                label: 'Participants'
                },
                {
                value: 'New contributors',
                label: 'New contributors'
                },
                {
                value: 'Inactive contributors',
                label: 'Inactive contributors'
                },
                {
                value: 'Bus factor',
                label: 'Bus factor'
                },
                {
                value: 'Issues new',
                label: 'Issues new'
                },
                {
                value: 'Issues closed',
                label: 'Issues closed'
                },
                {
                value: 'Issue comments',
                label: 'Issue comments'
                },
                {
                value: 'Issue response time',
                label: 'Issue response time'
                },
                {
                value: 'Issue resolution duration',
                label: 'Issue resolution duration'
                },
                {
                value: 'Issue age',
                label: 'Issue age'
                },
                {
                value: 'Code change lines',
                label: 'Code change lines'
                },
                {
                value: 'Change requests(Open PR)',
                label: 'Change requests(Open PR)'
                },
                {
                value: 'Change requests reviews',
                label: 'Change requests reviews'
                },
                {
                value: 'Change request response time',
                label: 'Change request response time'
                },
                {
                value: 'Change request resolution duration',
                label: 'Change request resolution duration'
                },
                {
                value: 'Change request age',
                label: 'Change request age'
                },
                {
                value: 'Activity Details',
                label: 'Activity Details'
                },
            ],
            
            }
        },
        methods:{
          // 清除所有的Timeout
          clearTimeouts(){
              this.timeouts.forEach((timeoutId)=>{
                clearTimeout(timeoutId);
              });
              this.timeouts= [];
          },
          // 继续播放
          resume(){
              this.isPaused=false;
              this.play();
          },
          // 暂停播放
          pause(){
            this.isPaused=true;
            this.clearTimeouts();
          },
          // 重复播放
          replay(){
            this.clearTimeouts();
            this.currentIndex=0;
            this.play();
          },
          updateMonth(month){
              const rich={};
              this.activityData[month].forEach((item)=>{
                rich[`avatar${item[0].replaceAll("-", "")}`] = {
                  backgroundColor:{
                    image:`https://avatars.githubusercontent.com/${item[0]}?s=48&v=4`
                  },
                  height:20
                };
              });
                      const option=this.generateEchartsOption();
                      option.yAxis.axisLabel.rich=rich;
                      option.series[0].data=this.activityData[month];
                      option.graphic.elements[0].style.text=month;
                      this.activityDetailsChart.setOption(option);
          },
          play(){
           
              // if(this.isPaused){
              //   return;
              // }
              const self=this;
              self.isPaused=false;
              self.playing=true;
              self.clearTimeouts();
              // let startIndex=0;
              for(let i=self.currentIndex;i<self.months.length-1;++i){
                  const timeoutId=setTimeout(function(){
                    if(!self.isPaused){
                      self.updateMonth(self.months[i+1]);
                      self.currentIndex=i+1;
                      if(i+1 === self.months.length-1){
                      self.playing=false;
                    }
                    }
                    
      
                  },(i -self.currentIndex)*self.updateFrequency);
                self.timeouts.push(timeoutId);
              }
          },
          generateEchartsOption(){
            const self=this;
              return {
                title:{
                    text:'Activity details',
                    left:'center'
                  },
                  tooltip: {
                    trigger: 'axis'
                  },
                          grid: {
                          top: 30,
                          bottom: 30,
                          left: 180,
                          right: 80
                        },
                        xAxis: {
                          max: "dataMax",
                          axisLabel: {
                            formatter: function (n) {
                              return Math.round(n) + "";
                            }
                          }
                        },
                        yAxis: {
                          type: "category",
                          inverse: true,
                          max: 10,
                          axisLabel: {
                            show: true,
                            fontSize: 14,
                            formatter: function (value) {
                              if (!value || value.endsWith("[bot]")) return value;
                              return `${value} {avatar${value.replaceAll("-", "")}|}`;
                            },
                            rich: null
                          },
                          animationDuration: 300,
                          animationDurationUpdate: 300
                        },
                        series: [
                          {
                            realtimeSort: true,
                            seriesLayoutBy: "column",
                            type: "bar",
                            itemStyle: {
                              color: function (params) {
                                const githubId = params.value[0];
                                if (self.colorMap.has(githubId)) {
                                  return self.colorMap.get(githubId);
                                } else {
                                  const randomColor =
                                    "#" + Math.floor(Math.random() * 16777215).toString(16);
                                  self.colorMap.set(githubId, randomColor);
                                  return randomColor;
                                }
                              }
                            },
                            data: null,
                            encode: {
                              x: 1,
                              y: 0
                            },
                            label: {
                              show: true,
                              precision: 1,
                              position: "right",
                              valueAnimation: true,
                              fontFamily: "monospace"
                            }
                          }
                        ],
                        // Disable init animation.
                        animationDuration: 0,
                        animationDurationUpdate: this.updateFrequency,
                        animationEasing: "linear",
                        animationEasingUpdate: "linear",
                        graphic: {
                          elements: [
                            {
                              type: "text",
                              right: 60,
                              bottom: 60,
                              style: {
                                text: null,
                                font: "bolder 60px monospace",
                                fill: "rgba(100, 100, 100, 0.25)"
                              },
                              z: 100
                            }
                          ]
                        }
                      };
          },
          initActivityDetailsChart(){
                this.activityDetailsChart=echarts.init(this.$refs.activity_details);
                this.activityDetailsChart.setOption(this.generateEchartsOption());
          },

           async getActivityDetailsData(url){
            try{
              const response=await this.$request.post('/api/data',{
                platform:"github",
                  org:"X-lab2017",
                  repo:"open-digger",
                  index:url
              })
              // const response=await axios.get(ROOT_PATH+url);
              this.activityData=this.filterYearMonthData(response.data);
              this.months=Object.keys(response.data).filter(key=>key.length === 7);
            }catch(e){
              this.$message.error('获取数据失败，请登录');
              this.$router.push('/login')
            }
          },
          // 获取change request的数据
          getChangeRequest(url1,url2,url3,option,chart){
                const request1=this.$request.post('/api/data',{
                  platform:"github",
                  org:"X-lab2017",
                  repo:"open-digger",
                  index:url1
                });
                const request2=this.$request.post('/api/data',{
                  platform:"github",
                  org:"X-lab2017",
                  repo:"open-digger",
                  index:url2
                });
                const request3=this.$request.post('/api/data',{
                  platform:"github",
                  org:"X-lab2017",
                  repo:"open-digger",
                  index:url3
                });
                axios.all([request1,request2,request3]).then(axios.spread((res1,res2,res3)=>{
                  let data1=res1.data;
                  let data2=res2.data;
                  let data3=res3.data;
                  let keys=Object.keys(data1).filter(key=>key.length === 7);
                  let crsNew=keys.map(key=>data1[key] ?? 0);
                  let crsAccepted=keys.map(key=>data2[key] ?? 0);
                  let crsReviews=keys.map(key=>data3[key] ?? 0);
                  option.xAxis.data=keys;
                  option.series[2].data=crsNew;
                  option.series[3].data=crsAccepted;
                  option.series[4].data=crsReviews;
                  chart.setOption(option);
                })).catch(() => {
              
                  this.$message.error('获取数据失败，请登录');
                  this.$router.push('/login')
                
            });
          },
          // 获取 code change lines数据
          getCodeChangesData(url1,url2,url3,option,chart){
            const request1=this.$request.post('/api/data',{
                  platform:"github",
                  org:"X-lab2017",
                  repo:"open-digger",
                  index:url1
                });
                const request2=this.$request.post('/api/data',{
                  platform:"github",
                  org:"X-lab2017",
                  repo:"open-digger",
                  index:url2
                });
                const request3=this.$request.post('/api/data',{
                  platform:"github",
                  org:"X-lab2017",
                  repo:"open-digger",
                  index:url3
                });
                axios.all([request1,request2,request3]).then(axios.spread((res1,res2,res3)=>{
                  let data1=res1.data;
                  let data2=res2.data;
                  let data3=res3.data;
                  // console.log(data1);
                  let keys=Object.keys(data1).filter(key=>key.length === 7);
                  let addCode=keys.map(key=>data1[key] ?? 0);
                  let removeCode=keys.map(key=> -data2[key] ?? 0);
                  let allChange=keys.map(key=>data3[key] ?? 0);
                  // console.log(addCode);
                  // console.log(removeCode);
                  option.xAxis.data=keys;
                  option.series[0].data=addCode;
                  option.series[1].data=removeCode;
                  option.series[2].data=allChange;
                  chart.setOption(option);
                })).catch(() => {
                      this.$router.push('/login');
                      this.$message.error('数据获取失败，请登录');
              });
          },
          // 获取issue response time的数据
          getIssueResponseTimeData(url,option,chart){

            this.$request.post('/api/data',{
              platform:"github",
                  org:"X-lab2017",
                  repo:"open-digger",
                  index:url
            }).then(res=>{
              let data=res.data;
              let months=Object.keys(data['avg']);
              let quantileData=months.map(m => [1, 3, 0, 4].map(q => data[`quantile_${q}`][m]));
              let avgData=months.map(m=>data['avg'][m]);
              // console.log(quantileData);
              // console.log(avgData);
              option.xAxis.data=months;
              option.series[0].data=quantileData;
              option.series[1].data=avgData;
              chart.setOption(option);
            }).catch(() => {
                      this.$router.push('/login');
                      this.$message.error('数据获取失败，请登录');
              });
          },
          // 获取issue new and closed的数据
          getDataIssueNewAndClosed(url1,url2,option,chart){
            const request1=this.$request.post('/api/data',{
                  platform:"github",
                  org:"X-lab2017",
                  repo:"open-digger",
                  index:url1
                });
                const request2=this.$request.post('/api/data',{
                  platform:"github",
                  org:"X-lab2017",
                  repo:"open-digger",
                  index:url2
                });

            axios.all([request1,request2]).then(axios.spread((res1,res2)=>{
              let data1=res1.data;
              let data2=res2.data;
              let months=Object.keys(data1).filter(key=>key.length === 7);
              let issuesNew=months.map(m=>data1[m]);
              let issuesClosed=months.map(m=>data2[m]);
              let issuesNewBase=[0];
              let issuesClosedBase=[];
              for(let i=1;i<issuesNew.length;i++){
                issuesNewBase.push(issuesNewBase[i-1]+issuesNew[i-1]-issuesClosed[i-1]);
              }
              for(let i=0;i<issuesNew.length;i++){
                issuesClosedBase.push(issuesNewBase[i]+issuesNew[i]-issuesClosed[i]);
              }
              option.xAxis.data=months;
              option.series[0].data=issuesNewBase;
              option.series[1].data=issuesClosedBase;
              option.series[2].data=issuesNew;
              option.series[3].data=issuesClosed;
              chart.setOption(option);
            })).catch(() => {
                      this.$router.push('/login');
                      this.$message.error('数据获取失败，请登录');
              });
  
          },
          //Bus Factor数据
          getBusFactorData(url,option,chart){
            this.$request.post('/api/data',{
              platform:"github",
                  org:"X-lab2017",
                  repo:"open-digger",
                  index:url
            }).then(res=>{
              let data=res.data;
              let keys=Object.keys(data).filter(key=>key.length === 7);
              let values=keys.map(key=>data[key]);
              option.xAxis.data=keys;
              option.series[0].data=values;
              option.series[1].data=values;
              chart.setOption(option);
            }).catch(() => {
                      this.$router.push('/login');
                      this.$message.error('数据获取失败，请登录');
              });
          },
          // 获取inactive contributors数据
          getinactiveContributors(url,option,chart){
            this.$request.post('/api/data',{
              platform:"github",
                  org:"X-lab2017",
                  repo:"open-digger",
                  index:url
            }).then(res=>{
              let data=res.data;
              let keys=Object.keys(data).filter(key=>key.length === 7);
              let values=keys.map(key=>-data[key] ?? 0);
              option.xAxis.data=keys;
              option.series[0].data=values;
              chart.setOption(option);
              
            }).catch(() => {
                      this.$router.push('/login');
                      this.$message.error('数据获取失败，请登录');
              });
          },
          //用于new contributors图表数据处理开始
              filterYearMonthData(data) {
          // 只保留键长度为7且符合 YYYY-MM 格式的数据项
          return Object.fromEntries(
            Object.entries(data).filter(([key]) => key.length === 7 && /^\d{4}-\d{2}$/.test(key))
          );
        },
        // 初始化new_contributors图表的数据
          initChart() {
            if(!this.contributorData || !Object.keys(this.contributorData).length)
            return;
            if(!this.contributorTree){
              this.contributorTree=echarts.init(this.$refs.new_contributors)
            }
          const option = {
            title:{
              text:'New Contributors',
              left:'center'
            },
            tooltip: {
              trigger: 'item',
              triggerOn: 'mousemove'
            },
            series: [
              {
                type: 'tree',
                data: [this.transformData()],
                top: '1%',
                left: '10%',
                bottom: '1%',
                right: '15%',
                symbolSize: 10,
                label: {
                  position: 'left',
                  verticalAlign: 'middle',
                  align: 'right',
                  fontSize: 12
                },
                leaves: {
                  label: {
                    position: 'right',
                    verticalAlign: 'middle',
                    align: 'left'
                  },
                  
                },
                emphasis: {
                focus: 'descendant'
                },
                expandAndCollapse: true,
                animationDuration: 550,
                animationDurationUpdate: 750
              }
            ]
          };

          this.contributorTree.setOption(option);
        },
        //把后端来的数据处理成echarts需要的格式（先要过滤掉键为7位的，再执行这个）
          transformData(){
            return {
          name: 'new_contributors', // 根节点名称
          children: Object.keys(this.contributorData).map(yearMonth => ({
            name: yearMonth,
            children: this.contributorData[yearMonth].map(name => ({ name }))
              }))
            };
            },
            // 异步函数，确保实例在请求完成再执行
            async getContributorData(url){
              try{
                const response = await this.$request.post('/api/data',{
                  platform:"github",
                  org:"X-lab2017",
                  repo:"open-digger",
                  index:url
                })
                // const response = await axios.get(ROOT_PATH+url);
                this.contributorData =this.filterYearMonthData(response.data);
                this.$nextTick(()=>{
                  this.initChart();
                })  
              }catch(e){
                      this.$router.push('/login');
                      this.$message.error('数据获取失败，请登录');
              }
 
            },
            //用于new contributors图表数据处理结束
            getParticipantData(url,option,chart){
              this.$request.post('/api/data',{
              platform:"github",
                  org:"X-lab2017",
                  repo:"open-digger",
                  index:url
            }).then(res=>{
                    let data=res.data;
                    let keys=Object.keys(data).filter(key=>key.length === 6);
                    // console.log(keys)
                    let values=keys.map(key=>data[key]);
                    let mergedArr= values.map((value,index)=>{
                        return {
                            value:value,
                            name: keys[index]
                        }
                    });
                    // console.log(mergedArr)
                    option.series[0].data=mergedArr;
                    chart.setOption(option);
                }).catch(() => {
                      this.$router.push('/login');
                      this.$message.error('数据获取失败，请登录');
              });
            },
            //柱状图加折线图（折线图为叠加求和）
            getStarData(url,option,chart){
              this.$request.post('/api/data',{
              platform:"github",
                  org:"X-lab2017",
                  repo:"open-digger",
                  index:url
            }).then(res => {
                    // console.log(res.data);
                    let data = res.data;
                    let accValue=[];
                    // 找出键的长度为7的键
                    let keys=Object.keys(data).filter(key =>key.length === 7);
                    // 求和
                    Object.keys(data).filter(key =>key.length === 7).map(key =>data[key]).reduce((p,c)=>{
                        accValue.push(p);
                        return p+c;
                    })
                    // console.log(accValue)
                    // 分别找出这些键对应的值
                    let line=keys.map(key=>data[key]);
                    // 将这些值赋值到横纵坐标
                    
                    option.xAxis.data = keys;
                    option.series[0].data = line;
                    option.series[1].data = accValue;
                    chart.setOption(option);
                }).catch(() => {
                      this.$router.push('/login');
                      this.$message.error('数据获取失败，请登录');
              });
            },
            // 获取数据并处理（热力图）
            getData(url,option,chart){
                // 小时
                const hours=[...Array(24).keys()];
                // 周几
                const weekday=['Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday'];
                this.$request.post('/api/data',{
              platform:"github",
                  org:"X-lab2017",
                  repo:"open-digger",
                  index:url
            }).then(res=>{
                    let data=res.data;
                    let values = Object.values(data).reduce((p, c) => {
                    if (p === null) return c;
                    return p.map((v, i) => v + c[i]);
                    }, null);
                    let max = Math.max(...values);
                    values = values.map(v => Math.ceil(v * 10 / max));
                    // console.log(values);
                    for(var d=0;d<7;d++){
                        for(var h=0;h<24;h++){
                            this.activeValue.push([h,6-d,values[d*24+h] || '-']);
                        }
                    }
              
                    option.xAxis.data=hours;
                    option.yAxis.data=weekday;
                    option.series[0].data=this.activeValue;
                    chart.setOption(option);
                    // console.log(this.activeValue)
                }).catch(() => {
                      this.$router.push('/login');
                      this.$message.error('数据获取失败，请登录');
              });
            },
            //提供搜索建议
            querySearch(queryString,cb){
                let data = this.data;
                let results= queryString?data.filter(this.createFilter(queryString)) : data;
                // 调用callback返回建议列表的数据
                cb(results);
            },
            createFilter(queryString){
                return (item)=>{
                    return (item.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0)
                }
            },
            // 下拉列表中的值
            loadAll(){
                return [{"value":"Active dates and times"},
                {"value":"Stars"},
                {"value":"Technical fork"},
                {"value":"Participants"},
                {"value":"New contributors"},
                {"value":"Inactive contributors"},
                {"value":"Bus factor"},
                {"value":"Issues new"},
                {"value":"Issues closed"},
                {"value":"Issue comments"},
                {"value":"Issue response time"},
                {"value":"Issue resolution duration"},
                {"value":"Issue age"},
                {"value":"Code change lines"},
                {"value":"Change requests(Open PR)"},
                {"value":"Change requests reviews"},
                {"value":"Change request response time"},
                {"value":"Change request resolution duration"},
                {"value":"Change request age"},
                {"value":"Activity Details"},
                ]
            },
            select() {
                let targetRef;
                switch (this.valueInput) {
                    case 'Active dates and times':
                        targetRef = this.$refs.active_dates_and_times;
                        break;
                    case 'Stars':
                        targetRef = this.$refs.stars;
                        break;
                    case 'Technical fork':
                        targetRef = this.$refs.technical_fork;
                        break;
                    case 'Participants':
                        targetRef = this.$refs.participants;
                        break;
                    case 'New contributors':
                        targetRef=this.$refs.new_contributors;
                        break;
                    case 'Inactive contributors':
                        targetRef=this.$refs.inactive_contributors;
                        break;
                    case 'Bus factor':
                        targetRef=this.$refs.bus_factor;
                        break;
                    case 'Issues new':
                        targetRef=this.$refs.issues_closed_and_new;
                        break;
                    case 'Issues closed':
                        targetRef=this.$refs.issues_closed_and_new;
                        break;
                    case 'Issue comments':
                        targetRef=this.$refs.issues_comments;
                        break;
                    case 'Issue response time':
                        targetRef=this.$refs.issue_response_time;
                        break;
                    case 'Issue resolution duration':
                        targetRef=this.$refs.issue_resolution_duration;
                        break;
                    case 'Issue age':
                        targetRef=this.$refs.issue_age;
                        break;
                    case 'Code change lines':
                        targetRef=this.$refs.code_change_lines;
                        break;
                    case 'Change requests(Open PR)':
                        targetRef=this.$refs.change_requests;
                        break;
                    case 'Change requests reviews':
                        targetRef=this.$refs.change_requests;
                        break;
                    case 'Change request response time':
                        targetRef=this.$refs.change_request_response_time;
                        break;
                    case 'Change request resolution duration':
                        targetRef=this.$refs.change_request_resolution_duration;
                        break;
                    case 'Change request age':
                        targetRef=this.$refs.change_request_age;
                        break;
                    case 'Activity Details':
                        targetRef=this.$refs.activity_details;
                        break;
                    default:
                        this.$message.error('请选择事件类型');
                        return;
                }
                if (targetRef) {
                    targetRef.scrollIntoView({ behavior: 'smooth' });
                }
                this.valueInput=''
            },
            handleSelect(item){
                console.log(item) 
            }
        },
        mounted(){
            this.data=this.loadAll();

            // active dates and times
            let activeDom = document.getElementById('active_dates_and_times');
            let activeChart = echarts.init(activeDom);
            activeChart.setOption(activeHeatMap);
            this.getData('active_dates_and_times', activeHeatMap, activeChart);

            // stars
            let starDom=document.getElementById('stars');
            let starChart=echarts.init(starDom);
            starChart.setOption(starBar);
            this.getStarData('stars',starBar,starChart);
            //technical fork
            let technicalDom=document.getElementById('technical_fork');
            let technicalChart=echarts.init(technicalDom);
            technicalChart.setOption(technicalBar);
            this.getStarData('technical_fork',technicalBar,technicalChart)
            //priticipants
            let participantDom=document.getElementById('participants');
            let participantChart=echarts.init(participantDom);
            // participantChart.setOption(participantPie);
            this.getParticipantData('participants',participantPie,participantChart);
            //new contributors
            this.initChart();
            //inactive contributors
            let inactiveDom=document.getElementById('inactive_contributors');
            let inactiveChart=echarts.init(inactiveDom);
            this.getinactiveContributors('inactive_contributors',inactiveContributorChart,inactiveChart);
            //bus factor
            let busFactorDom=document.getElementById('bus_factor');
            let busFactorChart=echarts.init(busFactorDom);
            this.getBusFactorData('bus_factor',busFactorBar,busFactorChart);
            //issues new and closed
            let issuesNewAndClosedDom=document.getElementById('issues_closed_and_new');
            let issuesNewAndClosedChart=echarts.init(issuesNewAndClosedDom);
            this.getDataIssueNewAndClosed('issues_new','issues_closed',issuesNewAndClosedK,issuesNewAndClosedChart);
            //issues comments
            let issuesCommentDom=document.getElementById('issues_comments');
            let issuesCommentChart=echarts.init(issuesCommentDom);
            this.getStarData('issue_comments',commentsBar,issuesCommentChart);
            //issue response time
            let issueResponseTimeDom=document.getElementById('issue_response_time');
            let issueResponseTimeChart=echarts.init(issueResponseTimeDom);
            this.getIssueResponseTimeData('issue_response_time',issueResponseTimeK,issueResponseTimeChart);
            //issue resolution duration
            let issueResolutionDom=document.getElementById('issue_resolution_duration');
            let issueResolutionChart=echarts.init(issueResolutionDom);
            this.getIssueResponseTimeData('issue_resolution_duration',issueResolutionK,issueResolutionChart);
            //issue age
            let issueAgeDom=document.getElementById('issue_age');
            let issueAgeChart=echarts.init(issueAgeDom);
            this.getIssueResponseTimeData('issue_age',issueAgeK,issueAgeChart);
            //code change lines
            let codeChangeLinesDom=document.getElementById('code_change_lines');
            let codeChangeLinesChart=echarts.init(codeChangeLinesDom);
            this.getCodeChangesData('code_change_lines_add','code_change_lines_remove','code_change_lines_sum',codeChangeLinesL,codeChangeLinesChart);

            //changes request
            let changeRequestDom=document.getElementById('change_requests');
            let changeRequestChart=echarts.init(changeRequestDom);
            this.getChangeRequest('change_requests','change_requests_accepted','change_requests_reviews',changeRequestBar,changeRequestChart);

            //Change request response time
            let changeRequestResponseTimeDom=document.getElementById('change_request_response_time');
            let changeRequestResponseTimeChart=echarts.init(changeRequestResponseTimeDom);
            this.getIssueResponseTimeData('change_request_response_time',crsResponseTimeK,changeRequestResponseTimeChart);
            //Change request resolution duration
            let changeRequestResolutionDom=document.getElementById('change_request_resolution_duration');
            let changeRequestResolutionChart=echarts.init(changeRequestResolutionDom);
            this.getIssueResponseTimeData('change_request_resolution_duration',crsResolutionDurationK,changeRequestResolutionChart);
            //Change request age
            let changeRequestAgeDom=document.getElementById('change_request_age');
            let changeRequestAgeChart=echarts.init(changeRequestAgeDom);
            this.getIssueResponseTimeData('change_request_age',crsResponseAgeK,changeRequestAgeChart);

            //activity details
            this.getActivityDetailsData('activity_details').then(()=>{
              this.$nextTick(()=>{
                this.initActivityDetailsChart();
              this.play();
              })
              
            })
        },
        created(){
          this.getContributorData('new_contributors_detail');
        },
        beforeDestroy(){
          if(this.activeChart){
            this.activeChart.clear();
          }
          // this.$refs.active_dates_and_times && this.$refs.active_dates_and_times.clear();
          if(this.starChart){
            this.starChart.clear();
          }
          // this.$refs.stars && this.$refs.stars.clear();
          if(this.technicalChart){
            this.technicalChart.clear();
          }
          // this.$refs.technical_fork && this.$refs.technical_fork.clear();
          if(this.participantChart){
            this.participantChart.clear();
          }
          // this.$refs.participants && this.$refs.participants.clear();
          if(this.activityDetailsChart){
            this.activityDetailsChart.clear();
          }
          // this.$refs.new_contributors && this.$refs.new_contributors.clear();
          if(this.busFactorChart){
            this.busFactorChart.clear();
          }
          // this.$refs.bus_factor && this.$refs.bus_factor.clear();
          if(this.issuesNewAndClosedChart){
            this.issuesNewAndClosedChart.clear();
          }
          // this.$refs.issues_closed_and_new && this.$refs.issues_closed_and_new.clear();
          if(this.issuesCommentChart){
            this.issuesCommentChart.clear();
          }
          // this.$refs.issues_comments && this.$refs.issues_comments.clear();
          if(this.issueResponseTimeChart){
            this.issueResponseTimeChart.clear();
          }
          // this.$refs.issue_response_time && this.$refs.issue_response_time.clear();
          if(this.changeRequestResolutionChart){
            this.changeRequestResolutionChart.clear();
          }
          // this.$refs.change_request_resolution_duration && this.$refs.change_request_resolution_duration.clear();
          if(this.changeRequestAgeChart){
            this.changeRequestAgeChart.clear();
          }
          // this.$refs.change_request_age && this.$refs.change_request_age.clear();
          // this.$refs.activity_details && this.$refs.activity_details.clear();
          // if(this.activityDetailsChart){
          //   this.activityDetailsChart.dispose();
          // }
        }
    }
</script>

<style scoped>

</style>